#include "datamedia.h"
#include "datamediavalidator.h"

#include <QDebug>
#include <QJsonDocument>
#include <QFileInfo>
#include "application.h"
#include "pubsubobject.h"

SINGLETON_IMPLIMENT(DataMedia)

DataMedia::DataMedia(QObject *parent)
    : QObject(parent)
{
    m_thread = new QThread();
    m_safety = new DataMediaSafety();
    TestThreadIsLocked(m_safety);
    m_safety->moveToThread(m_thread);
    m_thread->start();
    m_thread->setObjectName("data_media");

    connect(this, &DataMedia::async_save, m_safety, &DataMediaSafety::save, Qt::QueuedConnection);

    DataMediaValidator dummy;
    Q_UNUSED(dummy)
}

DataMedia::~DataMedia()
{
    delete m_safety;
    delete m_thread;
}

bool DataMedia::load(const QString &fileName, QByteArray &data) const
{
    // 先转换成绝对路径
    QFileInfo info(fileName);
    QString fn = info.fileName();
    QString fnBak = info.absolutePath() + "/." + fn;
    fn = info.absoluteFilePath();

    // 双文件检查
    if (!DataMediaValidator::isValid(fn)) // 原文件无效
    {
        qWarning() << fn << "is inValid";
        if (!DataMediaValidator::isValid(fnBak)) // 2份文件都无效，则报错，返回
        {
            qWarning() << fn << "is inValid";
            return false;
        }
        else // 备份文件有效，则从备份文件恢复原文件
        {
            DataMediaSafety::copy(fnBak, fn);
        }
    }
    else // 原文件有效，检查一下备份文件有没问题
    {
        if (!DataMediaValidator::isValid(fnBak)) // 备份文件无效，则恢复备份文件
        {
            qWarning() << fn << "is inValid";
            DataMediaSafety::copy(fn, fnBak);
        }
        else // 在2份文件都有效的情况下，比较2份文件是否相同，如果不同，则原文件覆盖备份文件
        {
            if (!DataMediaValidator::compare(fn, fnBak))
                DataMediaSafety::copy(fn, fnBak);
        }
    }

    // 读取数据
//    if (!QFile::exists(fn))
//    {
//        qWarning() << "The file " << fn << "is not exist";
//        return false;
//    }
    QFile file(fn);
    if (!file.open(QIODevice::ReadOnly))
    {
        qWarning() << "Couldn't open the file, " << fn;
        return false;
    }
    data = file.readAll();
    file.close();

    // 如果文件最后有校验数据，则剔除后面的校验数据再返回
    if (!DataMediaValidator::isValid(data))
        return false;

    data = DataMediaValidator::removeVerifyCode(data);
    return true;
}

bool DataMedia::save(const QString &fileName, QByteArray &data)
{
//    m_safety->save(fileName, data);

    // 文件保存放到独立线程运行
    emit async_save(fileName, data);

    return true;
}

bool DataMedia::restore(const QString &fileName)
{
    QFileInfo fileInfo('.' + fileName);
    QString absFileName = fileInfo.absoluteFilePath();
    if (!QFile::exists(absFileName))
    {
        qWarning() << "The file " << absFileName << "is not exist";
        return false;
    }

    QFile file(absFileName);
    if (!file.open(QIODevice::ReadOnly))
    {
        qWarning() << "Couldn't open the file, " << absFileName;
        return false;
    }
    QByteArray data = file.readAll();
    file.close();

    // 如果文件最后有校验数据，则剔除后面的校验数据再返回
    if (!DataMediaValidator::isValid(data))
        return false;
    else
    {
        data = DataMediaValidator::removeVerifyCode(data);
        // 恢复文件
        QFileInfo fileInfo(fileName);
        QString originAbsFileName = fileInfo.absoluteFilePath();
        DataMediaSafety::copy(originAbsFileName, absFileName);
    }
    return true;
}
